﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using IECAS.ERS.Services.Pop3;

namespace IECAS.ERS.Services
{
    public class MailReceive:IDisposable
    {
        private string _username;
        private string _password;
        private string _server;
        private Pop3Client _clientPop3 =null;

        /// <summary>
        /// new Pop3Client("xuzhisong520@126.com", "3901053", "pop3.126.com")
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="server"></param>
        public MailReceive(string username,string password,string server)
        {
            _username = username;
            _password = password;
            _server = server;
            _clientPop3 = new Pop3Client();//username, password, server);
        }

        public Pop3Client ClientPop3
        {
            get { return _clientPop3; }
        }
        
        public bool Login(out int mailCount,out StringBuilder str)
        {
            str = new StringBuilder();
            mailCount = 0;
            _clientPop3 = new Pop3Client();
            try
            {
                _clientPop3.Connect(_server);
                str.AppendLine("连接邮件服务器成功: " + _server);
            }
            catch (Exception ex)
            {
                str.AppendLine("连接邮件服务器失败: " + ex.Message);
                return false;
            }
            try
            {
                
                Pop3OperationResult res = _clientPop3.Authenticate(_username, _password);
                if (!res.IsSuccessful)
                {
                    str.AppendLine("登录邮件服务器失败: " + res.Message);
                    return false;
                }
                str.AppendLine("登录邮件服务器成功: " + _username + " " + res.Message);
                Pop3StatOperationResult statResult = _clientPop3.RetrieveState();
                if (!statResult.IsSuccessful)
                {
                    str.AppendLine(statResult.Message);
                    return false;
                }
                str.AppendLine("获取邮件服务器状态成功: " + "共有邮件数量[" + statResult.MessageCount.ToString()+"]");
                mailCount = statResult.MessageCount;
                return true;
            }
            catch(Exception ex)
            {
                str.AppendLine("通信故障: " + ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailIndex">邮件的索引从1开始</param>
        /// <param name="str"></param>
        /// <returns></returns>
        public string ReadUIDL(int mailIndex, out StringBuilder str)
        {
            str = new StringBuilder();
            if (_clientPop3 == null || _clientPop3.State != Pop3ConnectionState.Transaction)
            {
                str.AppendLine("没有连接或登录Pop3服务器: ");
                return null;
            }
            Pop3StatOperationResult uidl = _clientPop3.RetrieveUIDL(mailIndex);
            if (uidl.IsSuccessful)
                return uidl.Message;
            else
            {
                str.AppendLine("Pop3服务器返回UIDL消息失败: " + uidl.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mailIndex">邮件的索引,从1开始</param>
        /// <returns></returns>
        public Pop3EmailMessage ReadMail(int mailIndex)
        {
            StringBuilder str = new StringBuilder();
            if (_clientPop3 == null || _clientPop3.State != Pop3ConnectionState.Transaction)
            {
                str.AppendLine("没有连接或登录Pop3服务器: ");
                return null;
            }
            try
            {
                Pop3MultilineOperationResult mres = _clientPop3.RetrieveMessage(mailIndex);
                if (!mres.IsSuccessful)
                {
                    str.AppendLine("无法检索邮件('" + mres.Message + "').");
                }
                string[] content = mres.GetContent();
                return Rfc822Parser.Parse(content);                 
            }
            catch (Rfc822ParserException ex)
            {
                str.AppendLine("解析邮件信息失败: " + ex.Message);
                return null;
            }
            catch (Exception ex)
            {
                str.AppendLine("解析邮件信息失败: " + ex.Message);
                return null;
            }
        }

        public bool ReadEmail(out StringBuilder str,out List<Pop3EmailMessage> emailMessages)
        {
            emailMessages = new List<Pop3EmailMessage>();
            str = new StringBuilder();
            using (Pop3Client p3c = new Pop3Client())
            {
                try
                {
                    p3c.Connect(_server);
                }
                catch (Exception ex)
                {
                    str.AppendLine("连接邮件服务器失败: " + ex.Message);
                    return false;
                }
                try
                {
                    Pop3OperationResult res = p3c.Authenticate(_username, _password);
                    if (!res.IsSuccessful)
                    {
                        str.AppendLine("登录邮件服务器失败: " + res.Message);
                        return false;
                    }
                    Pop3StatOperationResult statResult = p3c.RetrieveState();
                    if (!statResult.IsSuccessful)
                    {
                        str.AppendLine(statResult.Message);
                        return false;
                    }
                    for (int i = 1; i < statResult.MessageCount + 1; i++)
                    {
                        Pop3StatOperationResult uidl = p3c.RetrieveUIDL(i);
                        Pop3EmailMessage msg;
                        try
                        {
                            //Try to read the message
                            Pop3MultilineOperationResult mres = p3c.RetrieveMessage(i);
                            if (!mres.IsSuccessful)
                            {
                                string availableMessages = "";
                                // We probably have an invalid message number; try to get STAT
                                // to show the available message numbers.
                                Pop3StatOperationResult stat = p3c.RetrieveState();
                                if (stat.IsSuccessful)
                                    availableMessages = " The mailbox has messages 1 - " + stat.MessageCount + ".";
                                str.AppendLine("无法检索邮件('" + mres.Message + "')." + availableMessages);//Could not retrieve the message
                                continue;
                            }
                            msg = Rfc822Parser.Parse(mres.GetContent());
                            if (uidl.IsSuccessful)
                                msg.UIDL = uidl.Message;
                            else
                            {
                                str.AppendLine("Pop3服务器返回UIDL消息失败: " + uidl.Message);
                                continue;
                            }
                            emailMessages.Add(msg);
                        }
                        catch (Rfc822ParserException ex)
                        {
                            str.AppendLine("解析邮件信息失败: " + ex.Message);
                            continue;
                        }
                        catch (Exception ex)
                        {
                            str.AppendLine("解析邮件信息失败: " + ex.Message);
                            continue;
                        }
                    }
                    p3c.Quit();
                    return true;
                }
                catch (Exception ex)
                {
                    str.AppendLine("通信故障: " + ex.Message);
                    return false;
                }
            }
        }

        public void Dispose()
        {
            try
            {
                if (_clientPop3 != null)
                {
                    _clientPop3.Quit();
                    _clientPop3.Dispose();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("释放Pop3连接失败："+ex.Message);
            }
        }
    }
}
